package easytasks.ui;

import java.io.Serializable;
import java.util.ArrayList;

import easytasks.data.DataSetup;
import easytasks.data.DataManager;
import easytasks.data.Task;
import easytasks.data.TaskCategory;
import easytasks.logic.DateFormatter;
import easytasks.logic.DateFormatter.DateAsStringType;
import easytasks.main.R;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.StrikethroughSpan;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;

public class TaskListActivity extends ListActivity
{
	private String action = null;
	private TaskCategory taskCategory = null;
	private AppMenu appMenu;

	private ArrayList<Task> tasks = null;
	private DataSetup dataInit;
	private DataManager dataManager;
	
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tasklist);
        
        action = getIntent().getStringExtra("action");
        if (action == null || action.equals("")) throw new IllegalArgumentException("Action not defined");
        
        if (action.equals("by-category"))
        {
        	Serializable taskCategoryReceived = getIntent().getSerializableExtra("category");
            if (taskCategoryReceived == null) throw new IllegalArgumentException("Input task category not defined.");
            if (!(taskCategoryReceived instanceof TaskCategory)) throw new IllegalArgumentException("Input task category not valid.");
            taskCategory = (TaskCategory)taskCategoryReceived;
        	
            if (taskCategory == null) throw new IllegalArgumentException("Task category not defined");
        }
        
        dataInit = new DataSetup(this);
        dataManager = new DataManager(dataInit, PreferenceManager.getDefaultSharedPreferences(this));
        
        if (action.equals("old")) appMenu = new AppMenu(this, R.id.itemOldTasks);
        else if (action.equals("by-category")) appMenu = new AppMenu(this, R.id.itemEditCategories);
        else appMenu = new AppMenu(this);
    }
    
    @Override
    public void onResume()
    {
    	super.onResume();
    	refresh();
    }
    
    private void refresh() 
    {
    	if (action.equals("today")) tasks = new ArrayList<Task>(dataManager.getTodayTasks());
        else if (action.equals("tomorrow")) tasks = new ArrayList<Task>(dataManager.getTomorrowTasks());
        else if (action.equals("current-week")) tasks = new ArrayList<Task>(dataManager.getCurrentWeekTasks());
        else if (action.equals("next-week")) tasks = new ArrayList<Task>(dataManager.getNextWeekTasks());
        else if (action.equals("by-category")) tasks = new ArrayList<Task>(dataManager.getTasksByCategory(taskCategory));
        else if (action.equals("old")) tasks = new ArrayList<Task>(dataManager.getOldTasks());
        else tasks = new ArrayList<Task>(dataManager.getTasks());

        setListAdapter(new TaskAdapter(this, R.layout.taskrow, tasks));
        refreshTitle();
        appMenu.refresh();
	}
    
    private void refreshTitle()
    {
    	if (action.equals("today"))
        {
        	setTitle(getString(R.string.tasklist_activity_today).replace("#0#", String.valueOf(dataManager.getTodayPendingTaskCount())));
        }
        else if (action.equals("tomorrow"))
        {
        	setTitle(getString(R.string.tasklist_activity_tomorrow).replace("#0#", String.valueOf(dataManager.getTomorrowPendingTaskCount())));
        }
        else if (action.equals("current-week"))
        {
        	setTitle(getString(R.string.tasklist_activity_currentweek).replace("#0#", String.valueOf(dataManager.getCurrentWeekPendingTaskCount())));
        }
        else if (action.equals("next-week"))
        {
        	setTitle(getString(R.string.tasklist_activity_nextweek).replace("#0#", String.valueOf(dataManager.getNextWeekPendingTaskCount())));
        }
        else if (action.equals("by-category"))
        {
        	setTitle(getString(R.string.tasklist_activity_categorytasks).replace("#0#", "\"" + taskCategory.getName() + "\"").replace("#1#", String.valueOf(dataManager.getPendingTaskByCategoryCount(taskCategory))));
        }
        else if (action.equals("old"))
        {
        	setTitle(getString(R.string.tasklist_activity_old).replace("#0#", String.valueOf(dataManager.getOldPendingTaskCount())));
        }
        else
        {
        	setTitle(getString(R.string.tasklist_activity_all).replace("#0#", String.valueOf(dataManager.getPendingTaskCount())));
        }
    }

	@Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {
    	Task selected = tasks.get(position);
    	Intent taskIntent = new Intent(this, TaskActivity.class);
    	taskIntent.putExtra("task", selected);
    	startActivity(taskIntent);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu)	
    {
    	super.onCreateOptionsMenu(menu);
    	return appMenu.onCreateOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
    	return appMenu.onOptionsItemSelected(item);
    }

    private class TaskAdapter extends ArrayAdapter<Task>
    {
    	private ArrayList<Task> taskList;
    	
    	public TaskAdapter(Context context, int textViewResourceId, ArrayList<Task> objects)
    	{
    		super(context, textViewResourceId, objects);
    		this.taskList = objects;
    	}

    	public View getView(int position, View convertView, ViewGroup parent)
    	{
    		LayoutInflater inflater = getLayoutInflater();
    		View row = inflater.inflate(R.layout.taskrow, parent, false);
    		
    		final Task entry = taskList.get(position);
    		final TextView textTitle = (TextView) row.findViewById(R.id.textTaskRowTitle);
    		final String title = entry.getTitle();   		
    		setRowTitleText(textTitle, title, entry);
    		
    		TextView textDate = (TextView) row.findViewById(R.id.textTaskRowDate);
    		DateFormatter formatter = new DateFormatter(TaskListActivity.this);
    		
    		if (action.equals("today") || action.equals("tomorrow")) textDate.setText(formatter.getTimeAsString(entry.getTime(), DateAsStringType.ONLY_HOUR, entry.getIgnoreHour()));
    		else textDate.setText(formatter.getTimeAsString(entry.getTime(), DateAsStringType.WEEKDAYDAY_AND_LONGMONTHANDHOUR, entry.getIgnoreHour()));
    		
    		if (textDate.getText().equals("")) textDate.setVisibility(View.GONE);
    		
    		CheckBox checkDone = (CheckBox) row.findViewById(R.id.checkTaskRowDone);
    		checkDone.setChecked(entry.isDone());
    		checkDone.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
				{
					dataManager.markTask(entry, isChecked);
					
					// We avoid calling "refresh" function for UI optimization,
					// but we must update task's "done" state, activity's
					// title and menu's "old tasks" count "manually".
					entry.markAsDone(isChecked);			
					refreshTitle();
					appMenu.refresh();
					
					setRowTitleText(textTitle, title, entry);
				}
			});
    		
    		return row;
    	}
    	
    	private void setRowTitleText(TextView textTitle, String title, Task entry)
    	{
    		if (entry.isDone()) setRowTitleTextFormat(textTitle, title, TextFormat.STRIKETHROUGH);
    		else setRowTitleTextFormat(textTitle, title, TextFormat.NORMAL);
    	}
    	
    	private void setRowTitleTextFormat(TextView textTitle, String title, TextFormat format)
    	{
    		if (format == TextFormat.NORMAL)
    		{
    			textTitle.setText(title);
    		}
    		else
    		{
    			Spannable text = new SpannableString(title);
	    		text.setSpan(new StrikethroughSpan(), 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	    		textTitle.setText(text);
    		}
    	}
    }
    
    public enum TextFormat
	{
		NORMAL, STRIKETHROUGH
	}
}
